import React, { useEffect, useState } from "react";
import './index.less';
import { ProTableOption, ProTableProps } from "./types";
import { Table, Button, TdPaginationProps, Row, Col, Form, Input, InputNumber, Select, Card, SubmitContext, DatePicker, TimePicker, RadioGroup, DateRangePicker, TimeRangePicker, RangeInput } from "tdesign-react";
import CheckboxGroup from "tdesign-react/es/checkbox/CheckboxGroup";
const { FormItem } = Form;

const ProTable = React.memo<ProTableProps>((props) => {

    const [formOptions, setFormOptions] = useState<any>();

    const [tableOptions, setTableOptions] = useState<any>();

    const [tableData, setTableData] = useState<any[]>([]);

    const [innerForm, setInnerForm] = useState<any>({});

    const [tableColumns, setTableColumns] = useState<any[]>([]);

    const [showMore, setShowMore] = useState<boolean>(true);

    const [page, setPage] = useState<TdPaginationProps>({
        current: 1,
        pageSize: 10,
    });

    const [keys, setKeys] = useState<string[]>([]);

    useEffect(() => {
        init();
        initRequest();
    }, []);

    function init() {
        initTableFormItem();
        initFormData();
    }

    function initRequest() {
        initTableData(page.current!, page.pageSize!);
    }

    function initFormData() {
        const formList = props.options.filter((option, index) => {
            option.formOrder = option.formOrder || index;
            return !option.hideInSearch
        }).sort((pre, cur) => pre.formOrder! - cur.formOrder!);
        const formObj: any = {};
        const keyList: string[] = [];
        setFormOptions(formList);
        formList.forEach(form => {
            const arryFormType = ['select', 'checkbox', 'timeRange', 'rangeInput', 'dateRange'];

            if (form.type && arryFormType.includes(form.type)) {
                formObj[form.key] = form.value || [];

                if (form.type === 'select' && !form.multiple) {

                    formObj[form.key] = form.value || void 0;
                }
            } else {
                if (typeof form.value === 'boolean') {
                    formObj[form.key] = form.value || false;
                } else {
                    formObj[form.key] = form.value || '';
                }
            }
            keyList.push(form.key);
        })
        setKeys(keyList);
        setInnerForm(formObj);

    }

    function initTableFormItem() {
        const tableList = props.options.filter((option, index) => {
            option.tableOrder = option.tableOrder || index;
            return !option.hideInTable;
        }).sort((pre, cur) => pre.tableOrder! - cur.tableOrder!);

        setTableOptions(tableList);

        const columns = new Array(tableList.length).fill(null).map((item, index) => ({
            colKey: tableList[index].key,
            cell: tableList[index].cell,
            title: tableList[index].title,
            width: tableList[index].width,
            render: tableList[index].render,
            foot: tableList[index].foot,
            children: tableList[index].children,
            fixed: tableList[index].fixed,
            colspan: tableList[index].colspan,
            ellipsis: tableList[index].ellipsis,
            ellipsisTitle: tableList[index].ellipsisTitle,
            stopPropagation: tableList[index].stopPropagation,
            edit: tableList[index].edit,
            ...tableList[index].tableAttrs
        }));

        setTableColumns(columns);
    }

    function initTableData(pageNum: number, pageSize: number) {
        if (!props.request) {
            throw new Error('request is required');
        }
        const form: any = {};

        keys.forEach(key => {
            form[key] = innerForm[key];
        })

        props.request({ pageNum, pageSize, form }).then(res => {
            setTableData(res.list);
            setPage({
                pageSize: pageSize,
                current: pageNum,
                total: res.total
            });
        })
    }


    function onSubmit(form: SubmitContext) {
        initTableData(1, page.pageSize!);
        setInnerForm({
            ...form.fields
        });
    }

    function formItemChange(key: string, e: any) {
        const form = { ...innerForm };
        form[key] = e;
        setInnerForm(form);
    }

    function renderFormItem(option: ProTableOption) {
        return <>
            <FormItem labelWidth={option.labelWidth || 70} {...option.formAttrs as any} rules={option.rules} label={option.title} labelAlign={option.labelAlign || 'left'} name={option.key}>
                {renderFormComponent(option)}
            </FormItem>
        </>
    }

    function renderFormComponent(option: ProTableOption) {
        const { type } = option;
        switch (type) {
            case 'input':
                return <><Input onChange={(e: any) => formItemChange(option.key, e)} defaultValue={option.value || ''} {...option.inputAttrs} style={{ width: '100%' }} placeholder={`请输入${option.title}`} /></>
            case 'number':
                return <><InputNumber onChange={(e: any) => formItemChange(option.key, e)} defaultValue={option.value || ''} {...option.inputNumberAttrs} style={{ width: '100%' }} theme={option.inputNumberAttrs?.theme || 'column'} placeholder={`请输入${option.title}`}></InputNumber></>
            case 'select':
                return <><Select onChange={(e: any) => formItemChange(option.key, e)} defaultValue={option.value || ''} {...option.selectAttrs} options={option.dataSource} placeholder={`请选择${option.title}`}></Select></>
            case 'date':
                return <><DatePicker className="w-full" onChange={(e: any) => formItemChange(option.key, e)} defaultValue={option.value || ''} {...option.datePickerAttrs} placeholder={`请选择${option.title}`}></DatePicker></>
            case 'checkbox':
                return <><CheckboxGroup onChange={(e: any) => formItemChange(option.key, e)} {...option.checkboxAttrs} defaultValue={option.value || ''} options={option.dataSource}></CheckboxGroup></>
            case 'time':
                return <><TimePicker className="w-full" onChange={(e: any) => formItemChange(option.key, e)} defaultValue={option.value || ''} {...option.timePickerAttrs} placeholder={`请选择${option.title}`}></TimePicker></>
            case 'radio':
                return <><RadioGroup onChange={(e: any) => formItemChange(option.key, e)} {...option.radioAttrs} defaultValue={option.value || ''} options={option.dataSource}></RadioGroup></>
            case 'dateRange':
                return <><DateRangePicker onChange={(e: any) => formItemChange(option.key, e)} defaultValue={option.value || ''} {...option.datePickerRageAttrs}></DateRangePicker></>
            case 'timeRange':
                return <><TimeRangePicker onChange={(e: any) => formItemChange(option.key, e)} defaultValue={option.value || ''} {...option.timePickerRangeAttrs}></TimeRangePicker></>
            case 'rangeInput':
                return <><RangeInput onChange={(e: any) => formItemChange(option.key, e)} {...option.inputRangeAttrs} defaultValue={option.value}></RangeInput></>
            default:
                return <><Input onChange={(e: any) => formItemChange(option.key, e)} defaultValue={option.value || ''} {...option.inputAttrs} style={{ width: '100%' }} placeholder={`请输入${option.title}`} /></>
        }
    }


    return <div className={'h-full overflow-auto'}>
        {
            !props.hideSearch && <div className="mb-5">
                <Card bordered={false} header={props.formHeader}>
                    <Form onSubmit={onSubmit} form={innerForm}>
                        <Row gutter={[16, 18]}>
                            {
                                formOptions ? formOptions.map((option: ProTableOption, index: number) => {
                                    if (index < 4) {
                                        return <Col span={option.span || 3} key={option.key} style={{ marginBottom: '12px' }}>
                                            {renderFormItem(option)}
                                        </Col>
                                    } else {
                                        return <Col span={option.span || 3} key={option.key} style={{ display: showMore ? 'block' : 'none', marginBottom: '12px' }}>
                                            {renderFormItem(option)}
                                        </Col>
                                    }
                                }) : null
                            }
                        </Row>

                        <Col span={12}>
                            <div className="text-right">
                                <Button style={{ marginRight: '12px' }} type="submit">
                                    {props.searchBtnText || '查询'}
                                </Button>
                                <Button style={{ marginRight: '12px' }} type="reset" theme="default" variant="base">
                                    {
                                        props.resetBtnText || '重置'
                                    }
                                </Button>
                                {
                                    (formOptions && formOptions.length > 4) && <Button onClick={() => setShowMore(!showMore)} theme="primary" variant="text">
                                        {showMore ? '收缩' : '展开'}
                                    </Button>
                                }
                            </div>
                        </Col>
                    </Form>

                </Card>

            </div>
        }

        {props.setting}
        
        <div>
            <Table
                ref={props.tableRef && props.tableRef}
                size={props.size || 'medium'}
                pagination={props.hidePagination === true ? undefined :
                    {
                        ...page,
                        size: props.size as any || 'small',
                        onChange: (pageInfo) => {
                            initTableData(pageInfo.current, pageInfo.pageSize);
                        }
                    }
                }
                {...props.tableAttrs}
                rowKey={props.rowKey}
                data={tableData}
                columns={tableColumns}

            />
        </div>
    </div>
});

export default ProTable;